﻿using System;
using System.ComponentModel;
using System.Windows.Data;

namespace Notoric.Gui.Converters
{
    /// <summary>
    /// Converts an <see cref="System.Collections.ICollection"/> instance to <see cref="ICollectionView"/>
    /// with possibility of filtering and sorting.
    /// </summary>
    [ValueConversion(typeof(System.Collections.ICollection), typeof(ICollectionView))]
    public class CollectionFilterSortConverter : IValueConverter
    {
        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="CollectionFilterSortConverter"/> class.
        /// </summary>
        public CollectionFilterSortConverter()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CollectionFilterSortConverter"/> class.
        /// </summary>
        /// <param name="filterHandler">
        /// <para>
        /// Type: <see cref="FilterEventHandler"/>
        /// </para>
        /// <para>
        /// The handler of the filter event.<br/>
        /// This argument can be <see langword="null"/> if the user does not need filtering.
        /// </para>
        /// </param>
        /// <param name="sortDescriptions">
        /// <para>
        /// Type: <see cref="SortDescriptionCollection"/>
        /// </para>
        /// <para>
        /// The sort descriptions.<br/>
        /// This argument can be <see langword="null"/> if the user does not need sorting.
        /// </para>
        /// </param>
        public CollectionFilterSortConverter(FilterEventHandler filterHandler, SortDescriptionCollection sortDescriptions)
        {
            this.filterHandler = filterHandler;
            this.sortDescriptions = sortDescriptions;
        }

        #endregion

        #region IValueConverter Members

        /// <inheritdoc/>
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value is System.Collections.ICollection)
            {
                var cvSource = new CollectionViewSource();
                cvSource.Source = value;
                if (filterHandler != null)
                    cvSource.Filter += filterHandler;
                if (sortDescriptions != null)
                {
                    foreach (var descr in sortDescriptions)
                        cvSource.SortDescriptions.Add(descr);
                }
                if (parameter != null)
                {
                    var sortProps = parameter.ToString().Split(',');
                    foreach (var prop in sortProps)
                        cvSource.SortDescriptions.Add(new SortDescription(prop, ListSortDirection.Ascending));
                }

                return cvSource.View;
            }
            else
                return false;
        }

        /// <inheritdoc/>
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets or sets the filter event handler.
        /// </summary>
        /// <value>
        /// <para>
        /// Type: <see cref="FilterEventHandler"/>
        /// </para>
        /// <para>
        /// The filter event handler.
        /// </para>
        /// </value>
        public FilterEventHandler Filter
        {
            get { return filterHandler; }
            set { filterHandler = value; }
        }

        /// <summary>
        /// Gets or sets the sort descriptions.
        /// </summary>
        /// <value>
        /// <para>
        /// Type: <see cref="SortDescriptionCollection"/>
        /// </para>
        /// <para>
        /// The sort descriptions.
        /// </para>
        /// </value>
        public SortDescriptionCollection SortDescriptions
        {
            get { return sortDescriptions; }
            set { sortDescriptions = value; }
        }

        #endregion

        #region Private Fields

        /// <summary>
        /// Holds the filter event handler.
        /// </summary>
        private FilterEventHandler filterHandler;
        /// <summary>
        /// Holds the sort descriptions.
        /// </summary>
        private SortDescriptionCollection sortDescriptions;

        #endregion
    }
}
